home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmbase-grok-1.2 / print.c < prev    next >
C/C++ Source or Header  |  1995-06-25  |  9KB  |  369 lines

  1. /*
  2.  * print all currently selected cards.
  3.  *
  4.  *    print()
  5.  */
  6.  
  7. #include "config.h"
  8. #include <X11/Xos.h>
  9. #include <stdio.h>
  10. #include <signal.h>
  11. #include <Xm/Xm.h>
  12. #include "grok.h"
  13. #include "form.h"
  14. #include "proto.h"
  15.  
  16. #define LLEN    79        /* printer line length, must be < 1024/3-1 */
  17. #define INDENT    8        /* note indentation in N format */
  18. #define TAB    8        /* tab stops every 8 characters */
  19.  
  20. #define SECT_OK(db,r) ((db)->currsect < 0 ||\
  21.                (db)->currsect == (db)->row[r]->section)
  22.  
  23. static void print_head_a(FILE *);
  24. static void print_tail_a(FILE *);
  25. static void print_card_a(FILE *, int);
  26. static void print_head_p(FILE *);
  27. static void print_tail_p(FILE *);
  28. static void print_card_p(FILE *, int);
  29.  
  30. extern int    errno;
  31. extern Widget    toplevel;    /* top-level shell for error popup */
  32. extern CARD     *curr_card;    /* card being displayed in main win */
  33. extern struct    pref pref;    /* global preferences */
  34.  
  35.  
  36. /*
  37.  * If the print spooler dies for some reason, print a message. Don't let
  38.  * grok die because of the broken pipe signal.
  39.  */
  40.  
  41. static void broken_pipe_handler(int sig)
  42. {
  43.     create_error_popup(toplevel, 0,
  44.             "Print failed, spooler aborted with signal %d\n", sig);
  45.     signal(SIGPIPE, SIG_IGN);
  46. }
  47.  
  48.  
  49. /*
  50.  * print mainline. Gets all the parameters from pref.
  51.  */
  52.  
  53. void print(void)
  54. {
  55.     FILE        *fp;        /* file or spooler to print to */
  56.     char        *file;        /* name of file or spooler */
  57.     char        path[128];    /* temp file name if to window */
  58.     int        n = 0;        /* misc */
  59.  
  60.     if (curr_card && curr_card->dbase && curr_card->form)
  61.         switch(pref.pselect) {
  62.           case 'C': n = curr_card->row;            break;
  63.           case 'S': n = curr_card->nquery;        break;
  64.           case 'A': n = curr_card->dbase->nrows;    break;
  65.         }
  66.     if (n == 0) {
  67.         create_error_popup(toplevel, 0, "No cards to print.");
  68.         return;
  69.     }
  70.     if (pref.pquality == 'P') {
  71.         create_error_popup(toplevel, 0, "PostScript not supported");
  72.         return;
  73.     }
  74.     signal(SIGPIPE, broken_pipe_handler);
  75.     file = pref.pfile;
  76.     switch(pref.pdevice) {
  77.       case 'P':
  78.         file = pref.pquality == 'P' ? pref.pspooler_a : pref.pspooler_a;
  79.         if (!(fp = popen(file, "w"))) {
  80.             create_error_popup(toplevel, errno,
  81.                 "Cannot open pipe to print spooler\n\"%s\"", file);
  82.             return;
  83.         }
  84.         break;
  85.  
  86.       case 'W':
  87.         sprintf(file = path, "/usr/tmp/grok%d", getpid());
  88.  
  89.       case 'F':
  90.         if (!(fp = fopen(file, "w"))) {
  91.             create_error_popup(toplevel, errno,
  92.                 "Cannot open print output file\n\"%s\"", file);
  93.             return;
  94.         }
  95.     }
  96.     if (pref.pquality == 'P')
  97.         print_head_p(fp);
  98.     else
  99.         print_head_a(fp);
  100.  
  101.     switch(pref.pselect) {
  102.       case 'C':
  103.         if (pref.pquality == 'P')
  104.             print_card_p(fp, n);
  105.         else
  106.             print_card_a(fp, n);
  107.         break;
  108.  
  109.       case 'S':
  110.         for (n=0; n < curr_card->nquery; n++)
  111.             if (pref.pquality == 'P')
  112.                 print_card_p(fp, curr_card->query[n]);
  113.             else
  114.                 print_card_a(fp, curr_card->query[n]);
  115.         break;
  116.  
  117.       case 'e':
  118.           for (n=0; n < curr_card->dbase->nrows; n++)
  119.             if (SECT_OK(curr_card->dbase, n))
  120.                 if (pref.pquality == 'P')
  121.                     print_card_p(fp, n);
  122.                 else
  123.                     print_card_a(fp, n);
  124.         break;
  125.  
  126.       case 'A':
  127.           for (n=0; n < curr_card->dbase->nrows; n++)
  128.             if (pref.pquality == 'P')
  129.                 print_card_p(fp, n);
  130.             else
  131.                 print_card_a(fp, n);
  132.     }
  133.     if (pref.pquality == 'P')
  134.         print_tail_p(fp);
  135.     else
  136.         print_tail_a(fp);
  137.  
  138.     switch(pref.pdevice) {
  139.       case 'P':
  140.         pclose(fp);
  141.         break;
  142.  
  143.       case 'F':
  144.         fclose(fp);
  145.         break;
  146.  
  147.       case 'W':
  148.         fclose(fp);
  149.         edit_file(file, TRUE, FALSE, "Grok Print", "editprint");
  150.         unlink(file);
  151.     }
  152. }
  153.  
  154.  
  155. /*----------------------------------------------------- ascii ---------------*/
  156. /*
  157.  * convert a line with max LLEN characters to bold or underline using ascii
  158.  * overstrike effects. This will not work well on magic-cookie terminals.
  159.  * As a side effect, truncates to LLEN characters. Does nothing if overstrike
  160.  * mode is off, or if the output goes to a window.
  161.  */
  162.  
  163. static void overstrike(
  164.     char        *text,        /* text to convert */
  165.     BOOL        underline)    /* TRUE=underline, FALSE=bold */
  166. {
  167.     char        buf[LLEN+1];    /* original text buffer */
  168.     char        *p, *q;        /* source and target copy pointers */
  169.  
  170.     text[LLEN] = 0;
  171.     if (pref.pquality != 'O' || pref.pdevice == 'W')
  172.         return;
  173.     strcpy(buf, text);
  174.     for (p=buf, q=text; *p; p++) {
  175.         *q++ = underline ? '_' : *p;
  176.         if (!underline || *p != ' ') {
  177.             *q++ = '\b';
  178.             *q++ = *p;
  179.         }
  180.     }
  181.     *q = 0;
  182. }
  183.  
  184.  
  185. /*
  186.  * print header (title line), for summary and summary+note formats
  187.  */
  188.  
  189. static void print_head_a(
  190.     FILE        *fp)        /* file or spooler to print to */
  191. {
  192.     char        buf[1024], *p;    /* summary line buffer */
  193.  
  194.     if (pref.pformat != 'C') {
  195.         make_summary_line(buf, curr_card, -1);
  196.         overstrike(buf, TRUE);
  197.         fprintf(fp, "%s\n", buf);
  198.         if (pref.pquality != 'O' || pref.pdevice == 'W') {
  199.             for (p=buf; *p; p++)
  200.                 *p = '-';
  201.             fprintf(fp, "%s\n", buf);
  202.         }
  203.     }
  204. }
  205.  
  206.  
  207. /*
  208.  * no trailer for ascii
  209.  */
  210.  
  211. /*ARGSUSED*/
  212. static void print_tail_a(
  213.     FILE        *fp)        /* file or spooler to print to */
  214. {
  215. }
  216.  
  217.  
  218. /*
  219.  * print one card to file fp. The first routine prints a string with a certain
  220.  * indentation and maximum length, specified separately for the first and
  221.  * continuation lines. The indentation counts towards the maximum length.
  222.  */
  223.  
  224. static void print_formatted(
  225.     FILE        *fp,        /* file or spooler to print to */
  226.     char        *text,        /* text to print */
  227.     int        in0,        /* indent of first line */
  228.     int        len0,        /* length of first line */
  229.     int        in1,        /* indent of other lines */
  230.     int        len1,        /* length of other lines */
  231.     BOOL        nl)        /* append trailing newline if TRUE */
  232. {
  233.     char        out[1024];    /* output line buffer */
  234.     register char    *p = text;    /* next source character from text */
  235.     register char    *q = out;    /* next target character in out[] */
  236.     int        len;        /* current output line length */
  237.  
  238.     while (p && *p) {
  239.         for (len=0; len < in0; len++)
  240.             *q++ = ' ';
  241.         while (*p && *p != '\n' && len <= len0) {
  242.             if (*p == '\t') {
  243.                 while (++len % TAB)
  244.                     *q++ = ' ';
  245.                 p++;
  246.             } else {
  247.                 len += *p == '\b' ? -1 : 1;
  248.                 *q++ = *p++;
  249.             }
  250.         }
  251.         while (nl && q != out && q[-1] == ' ')
  252.             q--;
  253.         *q = 0;
  254.         q    = out;
  255.         p   += *p == '\n';
  256.         in0  = in1;
  257.         len0 = len1;
  258.         fprintf(fp, "%s", out);
  259.         if (nl || *p)
  260.             fprintf(fp, "\n");
  261.     }
  262. }
  263.  
  264.  
  265. static void print_card_a(
  266.     FILE        *fp,        /* file or spooler to print to */
  267.     int        num)        /* card number to print */
  268. {
  269.     ITEM        *item;        /* contains info about formatting */
  270.     char        buf[1024];    /* summary line buffer */
  271.     char        *label;        /* if C format, label in left column */
  272.     char        *data;        /* data string from the database */
  273.     int        i;        /* item counter */
  274.     int        len;        /* output line length */
  275.     int        label_len = 0;    /* width of label column if C format */
  276.  
  277.     switch(pref.pformat) {
  278.       case 'S':
  279.         make_summary_line(buf, curr_card, num);
  280.         buf[LLEN] = 0;
  281.         print_formatted(fp, buf, 0, LLEN, 0, LLEN, TRUE);
  282.         break;
  283.  
  284.       case 'N':
  285.         make_summary_line(buf, curr_card, num);
  286.         overstrike(buf, FALSE);
  287.         print_formatted(fp, buf, 0, LLEN, 0, LLEN, TRUE);
  288.         for (i=0; i < curr_card->nitems; i++) {
  289.             item = curr_card->form->items[i];
  290.             if (item->type != IT_NOTE)
  291.                 continue;
  292.             print_formatted(fp, dbase_get(curr_card->dbase,
  293.                             num, item->column),
  294.                         INDENT, LLEN, INDENT, LLEN, TRUE);
  295.             fprintf(fp, "\n");
  296.         }
  297.         break;
  298.  
  299.       case 'C':
  300.         for (i=0; i < curr_card->nitems; i++) {
  301.             item = curr_card->form->items[i];
  302.             len = strlen(item->label ? item->label :
  303.                      item->name  ? item->name  : "--");
  304.             if (len > label_len)
  305.                 label_len = len;
  306.         }
  307.         label_len += 2;
  308.         for (i=0; i < curr_card->nitems; i++) {
  309.             item  = curr_card->form->items[i];
  310.             data  = dbase_get(curr_card->dbase, num, item->column);
  311.             label = item->label ? item->label :
  312.                 item->name  ? item->name  : "--";
  313.             switch(item->type) {
  314.               case IT_INPUT:
  315.               case IT_NOTE:
  316.                 break;
  317.               case IT_TIME:
  318.                 data = format_time_data(data, item->timefmt);
  319.                 break;
  320.               case IT_CHOICE: {
  321.                 char *c = item->flagcode;
  322.                 if (!data || !c || strcmp(data, c))
  323.                     continue;
  324.                 label = item->name  ? item->name  : "--";
  325.                 data  = item->label ? item->label : c?c : "--";
  326.                 break; }
  327.               case IT_FLAG:
  328.                 data = !data || !item->flagcode || strcmp(data,
  329.                         item->flagcode) ? "no" : "yes";
  330.                 break;
  331.               case IT_PRINT:
  332.                 data = evaluate(curr_card, item->idefault);
  333.                 break;
  334.               default:
  335.                 continue;
  336.             }
  337.             if (!data || !*data)
  338.                 continue;
  339.             strcpy(buf, label);
  340.             for (len=strlen(buf); len < label_len; len++)
  341.                 strcat(buf, " ");
  342.             overstrike(buf, FALSE);
  343.             print_formatted(fp, buf, 0, LLEN, 0, LLEN, FALSE);
  344.             print_formatted(fp, data, 0, LLEN-label_len,
  345.                             label_len, LLEN, TRUE);
  346.         }
  347.         fprintf(fp, "\n");
  348.         break;
  349.     }
  350. }
  351.  
  352.  
  353. /*----------------------------------------------------- PostScript ----------*/
  354. static void print_head_p(
  355.     FILE        *fp)        /* file or spooler to print to */
  356. {
  357. }
  358.  
  359. static void print_tail_p(
  360.     FILE        *fp)        /* file or spooler to print to */
  361. {
  362. }
  363.  
  364. static void print_card_p(
  365.     FILE        *fp,        /* file or spooler to print to */
  366.     int        num)        /* card number to print */
  367. {
  368. }
  369.